using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Evolution.Engine.Managers;

namespace Evolution.Engine
{
	public class Shader
    {
		private string _Asset;
		private Effect _Effect;

		public Effect Effect { get { return _Effect; } }

		public Shader(string asset)
        {
			_Asset = asset;
		}

		public void SetParameters(BaseObject obj)
        {
            if (_Effect.Parameters["World"] != null)
                _Effect.Parameters["World"].SetValue(obj.World);

            if (_Effect.Parameters["View"] != null)
                _Effect.Parameters["View"].SetValue(CameraManager.Instance.ActiveCamera.View);

            if (_Effect.Parameters["ViewI"] != null)
                _Effect.Parameters["ViewI"].SetValue(Matrix.Invert(CameraManager.Instance.ActiveCamera.View));
            
			if(_Effect.Parameters["Projection"] != null)
                _Effect.Parameters["Projection"].SetValue(CameraManager.Instance.ActiveCamera.Projection);

			if(_Effect.Parameters["EyePosition"] != null)
                _Effect.Parameters["EyePosition"].SetValue(CameraManager.Instance.ActiveCamera.Position);

            if (_Effect.Parameters["WVP"] != null)
                _Effect.Parameters["WVP"].SetValue(obj.World * CameraManager.Instance.ActiveCamera.ViewProjection);

            if (_Effect.Parameters["WorldView"] != null)
                _Effect.Parameters["WorldView"].SetValue(CameraManager.Instance.ActiveCamera.ViewProjection);
            
            if (LightManager.Instance.ActiveLights.Count > 0)
            {
                SetParameter("LightCount", LightManager.Instance.ActiveLights.Count);
                SetParameter("LightPosition", LightManager.Instance.Positions.ToArray());
                SetParameter("LigthPower", LightManager.Instance.Power.ToArray());
                SetParameter("LightDiffuseColor", LightManager.Instance.Diffuse.ToArray());
                SetParameter("LigthSpecularColor", LightManager.Instance.Specular.ToArray());
                SetParameter("LightAmbientColor", LightManager.Instance.Ambient.ToArray());
                SetParameter("LightType", LightManager.Instance.Type.ToArray());
            }
            else
            {
                //List<Vector3> pos = new List<Vector3>();
                //List<Vector4> dif = new List<Vector4>();

                //SetParameter("LightCount", 1);
                
                //pos.Add(EnvironmentManager.Instance.SkyObjects[0].Position);
                //dif.Add(EnvironmentManager.Instance.SkyObjects[0].Diffuse);

                //SetParameter("LightPosition", pos.ToArray());
                //SetParameter("LightDiffuseColor", dif.ToArray());

                //pos = null;
                //dif = null;
            }
        }

        #region Parameter sets
        public void SetParameter(string paramName, float[] paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }

        public void SetParameter(string paramName, int[] paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        public void SetParameter(string paramName, int paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        public void SetParameter(string paramName, float paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        public void SetParameter(string paramName, Vector3 paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        public void SetParameter(string paramName, Vector3[] paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        public void SetParameter(string paramName, Vector4[] paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        public void SetParameter(string paramName, Matrix[] paramData)
        {
            if (_Effect.Parameters[paramName] != null)
                _Effect.Parameters[paramName].SetValue(paramData);
        }
        #endregion

        public void Load() 
        {
			if(_Asset == "BasicEffect") 
            {
				_Effect = new BasicEffect(GameEngine.Instance.Device, null);
			} 
            else
            {
				_Effect = ResourceManager.Instance.LoadContent<Effect>(_Asset);
			}
		}
	}
}